#include <stdlib.h>
#include <stdio.h>
#include "ListaFiesta.h"
#include "Fiesta.h"

ListaFiesta* crear_ListaFiesta(){
    ListaFiesta* lista= malloc(sizeof(ListaFiesta));
    lista->cant=0;
    lista->fin=NULL;
    lista->fin_arch=NULL;
    lista->ini=NULL;
    return lista;
}

ListaFiesta nueva_ListaFiesta(){
    ListaFiesta lista;
    lista.cant=0;
    lista.fin=NULL;
    lista.fin_arch=NULL;
    lista.ini=NULL;
    return lista;
}

void insertarFinal_ListaFiesta(ListaFiesta* lista, Fiesta* fiesta){
    NodoListaFiesta* nuevo = malloc(sizeof(NodoListaFiesta));
    nuevo->fiesta=fiesta;
    nuevo->ant=lista->fin;
    nuevo->sig=NULL;
    if(lista->cant == 0){
        lista->ini=nuevo;
    }
    else{
        lista->fin->sig=nuevo;
    }
    lista->fin=nuevo;
    (lista->cant)+=1;
}

void imprimir_ListaFiesta(ListaFiesta* L){
    NodoListaFiesta* i;
    for (i = L->ini; i != NULL; i = i->sig){
        imprimir_Fiesta(i->fiesta);
    }
}
void imprimir_ListaFiesta_des(ListaFiesta* L){
    NodoListaFiesta* i;
    for (i = L->fin; i != NULL; i = i->ant){
        imprimir_Fiesta(i->fiesta);
    }
}

NodoListaFiesta* rem_ini_ListaFiesta(ListaFiesta *L){
    NodoListaFiesta *aux;
    aux = L->ini;
    if(L->cant<=1){
        L->ini=NULL;
        L->fin=NULL;
    }else{
        L->ini=L->ini->sig;
    }
    (L->cant)--;
    return aux;
}

void separar_ListaFiesta(ListaFiesta *L, ListaFiesta *l, ListaFiesta *r){
    int i;
    NodoListaFiesta *aux;
    Fiesta *a;
    int num=(L->cant)/2;
    int num1 = L->cant;
    for(i=0;i<num;i++){
        aux = rem_ini_ListaFiesta(L);
        a = aux->fiesta;
        insertarFinal_ListaFiesta(l,a);
    }
    for(i=num;i<num1;i++){
        aux = rem_ini_ListaFiesta(L);
        a = aux->fiesta;
        insertarFinal_ListaFiesta(r,a);
    }
    
}

int comp_ListaFiesta(ListaFiesta *l,ListaFiesta *r,int campo){
    if(campo == 0){
        if((l->ini->fiesta->codigo)<=(r->ini->fiesta->codigo)) return 1;
        return 0;
    }else if(campo == 1){
        if(strcmp(l->ini->fiesta->nombre,r->ini->fiesta->nombre)==-1) return 1;
        return 0;
    }else if(campo == 2){
        if((l->ini->fiesta->costo)<=(r->ini->fiesta->costo))return 1;
        return 0;
    }else if(campo == 3){
        if((valor_Fecha(l->ini->fiesta->fecha)<=valor_Fecha(r->ini->fiesta->fecha)))return 1;
        return 0;
    }
}

void merge_ListaFiesta(ListaFiesta *L,ListaFiesta *l,ListaFiesta *r,int campo){
    NodoListaFiesta *aux;
    Fiesta *a;
    
    while(l->cant>0 || r->cant>0){
        if(l->cant>0 && r->cant>0){
            if(comp_ListaFiesta(l,r,campo)){
                aux = rem_ini_ListaFiesta(l);
                a = aux->fiesta;
                insertarFinal_ListaFiesta(L,a);
            }else{
                aux = rem_ini_ListaFiesta(r);
                a = aux->fiesta;
                insertarFinal_ListaFiesta(L,a);
            }
        }else if(l->cant>0){
            aux = rem_ini_ListaFiesta(l);
                a = aux->fiesta;
                insertarFinal_ListaFiesta(L,a);
        }else if(r->cant>0){
            aux = rem_ini_ListaFiesta(r);
                a = aux->fiesta;
                insertarFinal_ListaFiesta(L,a);
        }
    }
}

void merge_sort_ListaFiesta(ListaFiesta *L, int campo){
    if(L->cant<=1)return;
    ListaFiesta l,r;
    l=nueva_ListaFiesta();
    r=nueva_ListaFiesta();
    separar_ListaFiesta(L,&l,&r);
    merge_sort_ListaFiesta(&l,campo);
    merge_sort_ListaFiesta(&r,campo);
    merge_ListaFiesta(L,&l,&r,campo);
}




